package cc.rboot.token.interceptor;

import cc.rboot._core.exception.TokenLogoutException;
import cc.rboot.token.core.IToken;
import cc.rboot.token.core.ITokenAware;
import cc.rboot.token.annotation.RequireToken;
import cc.rboot.token.tokens.NoneToken;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Resource
    public ITokenAware tokenAware;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = ((HandlerMethod) handler);

        RequireToken requireToken = handlerMethod.getMethodAnnotation(RequireToken.class);
        if (requireToken == null) {
            requireToken = handlerMethod.getBeanType().getAnnotation(RequireToken.class);
        }

        /**
         * 没使用注解时：如果已登录就放行，未登录就报错
         */
        if (requireToken == null) {
            if (!tokenAware.isLogin()) {
                tokenAware.logout();
                throw new TokenLogoutException();
            }
            return true;
        }

        /**
         * 有注解时，遍历：如果是NoneToken就放心，如果按照class鉴权成功就放行
         */
        for (Class<? extends IToken> aClass : requireToken.value()) {
            if(aClass.equals(NoneToken.class)) {
                return true;
            }
            if (tokenAware.get(aClass) != null) {
                return true;
            }
        }
        /**
         * 都不行就报错
         */
        tokenAware.logout();
        throw new TokenLogoutException();
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    }
}
